<?php
namespace App\Services;

use App\Event\UserRegister;
use App\Helper\Utils;
use App\Model\User;
use App\Model\UserAccount;
use App\Model\UserInfo;
use App\Model\UserWechat;
use App\Repositories\SmsCodeRespository;
use App\Repositories\UserAccountRepository;
use App\Repositories\UserRepository;
use App\Repositories\UserWechatRepository;
use App\Traits\ReturnTrait;
use function EasyWeChat\Kernel\Support\get_client_ip;
use Hyperf\DbConnection\Db;
use Hyperf\Di\Annotation\Inject;
use Hyperf\HttpServer\Contract\RequestInterface;
use mysql_xdevapi\Exception;
use Phper666\JwtAuth\Jwt;
use Psr\EventDispatcher\EventDispatcherInterface;

class UserService
{
    use ReturnTrait;
    /**
     * @Inject
     * @var EventDispatcherInterface
     */
    private $eventDispatcher;
    /**
     * @Inject
     * @var Jwt
     */
    private $jwt;

    /**
     * @Inject
     * @var SessionService
     */
    private $sessionService;

    public function refreshToken(){
        $token = $this->jwt->refreshToken();
//        $tokenobj = $this->jwt->getTokenObj();
//        if ($this->jwt->checkToken()) {
//            $userId = $tokenobj->getClaim('user_id');
//            $user = User::where('id', $userId)->first();
//            if (!$user) {
//                return $this->error('用户不存在或者已删除');
//            }
//        }
//        $userId = $token->getClaim('user_id');
//        $user = User::where('id', $userId)->first();
//        if(!$user){
//            return $this->error('用户不存在或者已删除');
//        }
        return $this->success([
            'access_token' => (string) $token,
            'expires_in' => $this->jwt->getTTL()
        ]);
    }

    public function signUp($data){
        $where = [
            [
                'field' => 'mobile',
                'value' => $data['mobile']
            ]
        ];
        $user = UserRepository::getInstance()->one('*',$where);
        if($user){
            return $this->error('手机号已存在');
        }
        $user_data =[
            'username' => User::generate_username(),
            'password' => password_hash($data['password'],PASSWORD_BCRYPT),
            'mobile' => $data['mobile'],
            'status' => User::STATUS_ON,
            'reg_time' => date('Y-m-d H:i:s'),
            'reg_ip' => get_client_ip()
        ];
        $return = UserRepository::getInstance()->store($user_data);
        if(!$return['success']){
            return $this->error('用户创建失败');
        }
        $user = $return['data'];
        return $this->success([
           'id' =>  $user->id
        ]);
    }

    public function webLogin($data){
        $mobile = $data['mobile'];
        $password = $data['password'];
        $where = [
            [
                'field' => 'mobile',
                'value' => $mobile
            ]
        ];
        $user = UserRepository::getInstance()->one('*',$where);
        if(!$user){
            return $this->error('用户不存在');
        }
        if(!password_verify($password,$user->password)){
            return $this->error('密码不正确');
        }
        $this->sessionService->set('user',$user);
        return $this->success([]);
    }

    public function quickLogin($data){
        $where = [
            [
                'field' => 'mobile',
                'value' => $data['mobile']
            ]
        ];
        $code = $data['code'];
        $result_code = SmsCodeRespository::getInstance()->one(['id','code'],[[
            'field' => 'mobile',
            'value' => $data['mobile']
        ]],[[
            'field' => 'id',
            'sort' => 'desc'
        ]]);
        if(!$result_code){
            return $this->error('验证码不正确');
        }
        if($result_code->code!=$code){
            return $this->error('验证码不正确');
        }
        $user = UserRepository::getInstance()->one('*',$where);
        $is_register = false;
        DB::beginTransaction();
        try {
            if(!$user){
                $is_register = true;
                $user_data =[
                    'username' => User::generate_username(),
                    'password' => password_hash(md5(config('common.init_pwd')),PASSWORD_BCRYPT),
                    'mobile' => $data['mobile'],
                    'status' => User::STATUS_ON,
                    'reg_time' => date('Y-m-d H:i:s'),
                    'reg_ip' => Utils::ip()
                ];
                $return = UserRepository::getInstance()->store($user_data);
                if(!$return['success']){
                    return $this->error('用户创建失败');
                }
                $user = $return['data'];
                $account_return = UserAccountRepository::getInstance()->store([
                    'user_id'=> $user->id,
                    'search_nums' => 0,
                    'used_search_nums' => 0,
                    'balance' => 0,
                    'used_balance' => 0,
                    'frozen_balance' => 0
                ]);
                if(!$account_return['success']){
                    throw new \Exception('用户账户创建失败');
                }
            }
            DB::commit();
        }catch(\Exception $e){
            DB::rollBack();
            return $this->error($e->getMessage());
        }
        if($is_register){
            $this->eventDispatcher->dispatch(new UserRegister($user,$data));
        }
        $token = (string) $this->jwt->getToken(['user_id' => $user->id]);
        return $this->success([
            'user' => $user,
            'access_token' => $token,
            'expires_in' => $this->jwt->getTTL(),
        ]);
    }

    public function wechatLogin($data){
        $where = [
            [
                'field' => 'mobile',
                'value' => $data['mobile']
            ]
        ];
        $user = UserRepository::getInstance()->one('*',$where);
        $is_register = false;
        DB::beginTransaction();
        try {
            if(!$user){
                $is_register = true;
                $user_data =[
                    'username' => User::generate_username(),
                    'password' => password_hash(md5(config('common.init_pwd')),PASSWORD_BCRYPT),
                    'mobile' => $data['mobile'],
                    'status' => User::STATUS_ON,
                    'reg_time' => date('Y-m-d H:i:s'),
                    'reg_ip' => get_client_ip(),
                    'is_virtual' => isset($data['is_virtual'])?$data['is_virtual']:0
                ];
                $return = UserRepository::getInstance()->store($user_data);
                if(!$return['success']){
                    throw new \Exception('用户创建失败');
                }
                $user = $return['data'];
                $account_return = UserAccountRepository::getInstance()->store([
                    'user_id'=> $user->id,
                    'balance' => 0,
                    'used_balance' => 0,
                    'frozen_balance' => 0
                ]);
                if(!$account_return['success']){
                    throw new \Exception('用户账户创建失败');
                }
                //保存微信信息
            }
            $wechat_user = UserWechatRepository::getInstance()->one('*', [
                [
                    'field' => 'user_id',
                    'value' => $user->id
                ]
            ]);
            $wechat_data=[
                'id' => $wechat_user?$wechat_user->id:0,
                'wx_openid' => $data['wx_openid'],
                'wx_nickname' => $data['nickName'],
                'wx_avatar' => $data['avatarUrl'],
                'user_id' => $user->id
            ];
            $return_wechat = UserWechatRepository::getInstance()->store($wechat_data);
            if(!$return_wechat['success']){
                throw new \Exception('微信信息同步失败');
            }
            DB::commit();
        }catch(\Exception $e){
            DB::rollBack();
            return $this->error($e->getMessage());
        }
        if($is_register){
            $this->eventDispatcher->dispatch(new UserRegister($user,$data));
        }
        $token = (string) $this->jwt->getToken(['user_id' => $user->id]);
        $account = UserAccountRepository::getInstance()->one('*',[[
            'field' => 'user_id',
            'value' => $user->id
        ]]);
        $user=collect($user)->toArray();
        $account = collect($account)->toArray();
        $user['account'] = $account;
        return $this->success([
            'user' => $user,
            'access_token' => $token,
            'expires_in' => $this->jwt->getTTL(),
            'is_register' => $is_register//是否新注册会员
            //'is_register' =>true
        ]);
    }

    public function loginByUserId($user_id){
        $user = UserRepository::getInstance()->getById($user_id);
        $is_register = false;
        $token = (string) $this->jwt->getToken(['user_id' => $user->id]);
        $account = UserAccountRepository::getInstance()->one('*',[[
            'field' => 'user_id',
            'value' => $user->id
        ]]);
        $user=collect($user)->toArray();
        $account = collect($account)->toArray();
        $user['account'] = $account;
        return $this->success([
            'user' => $user,
            'access_token' => $token,
            'expires_in' => $this->jwt->getTTL(),
            'is_register' => $is_register//是否新注册会员
            //'is_register' =>true
        ]);
    }

    public function wechatByOpenidLogin($data){
        $channel = isset($data['channel'])?$data['channel']:'default';
        $user_wechat=null;
        if($data['unionid']){
            $where_unionid = [
                [
                    'field' => 'unionid',
                    'value' => $data['unionid']
                ]
            ];
            $user_wechat = UserWechatRepository::getInstance()->one('*',$where_unionid);
        }
        if(!$user_wechat){
            $where = [
                [
                    'field' => 'wx_openid',
                    'value' => $data['wx_openid']
                ]
            ];
            $user_wechat = UserWechatRepository::getInstance()->one('*',$where);
        }

        $is_register = false;
        DB::beginTransaction();
        try {
            if(!$user_wechat){
                $is_register = true;
                $user_data =[
                    'username' => User::generate_username(),
                    'password' => password_hash(md5(config('common.init_pwd')),PASSWORD_BCRYPT),
                    //'mobile' => $data['mobile'],
                    'status' => User::STATUS_ON,
                    'reg_time' => date('Y-m-d H:i:s'),
                    'reg_ip' => get_client_ip()
                ];
                $return = UserRepository::getInstance()->store($user_data);
                if(!$return['success']){
                    throw new \Exception('用户创建失败');
                }
                $user = $return['data'];
                $account_return = UserAccountRepository::getInstance()->store([
                    'user_id'=> $user->id,
                    'search_nums' => 0,
                    'used_search_nums' => 0,
                    'balance' => 0,
                    'used_balance' => 0,
                    'frozen_balance' => 0
                ]);
                if(!$account_return['success']){
                    throw new \Exception('用户账户创建失败');
                }
                //保存微信信息
            }else{
                $user = UserRepository::getInstance()->one('*',[[
                    'field' => 'id',
                    'value' => $user_wechat->user_id
                ]]);
            }
            $wechat_data=[
                'id' => $user_wechat?$user_wechat->id:0,
                'wx_openid' => $data['wx_openid'],
                'unionid' => $data['unionid'],
                'wx_nickname' => $data['nickName'],
                'wx_avatar' => $data['avatarUrl'],
                'user_id' => $user->id
            ];
            $return_wechat = UserWechatRepository::getInstance()->store($wechat_data);
            if(!$return_wechat['success']){
                throw new \Exception('微信信息同步失败');
            }
            $openid_channel_record = UserOpenidChannelRepository::getInstance()->one('*',[[
                'field' => 'user_id',
                'value' => $user->id
            ],[
                'field' => 'channel',
                'value' => $channel
            ]]);
            $openid_channel_data=[
                'id' => $openid_channel_record?$openid_channel_record->id:0,
                'wx_openid' => $data['wx_openid'],
                'channel' =>$channel,
                'user_id' => $user->id
            ];
            $return_channel = UserOpenidChannelRepository::getInstance()->store($openid_channel_data);
            if(!$return_channel['success']){
                throw new \Exception('微信信息同步失败');
            }
            DB::commit();
        }catch(\Exception $e){
            DB::rollBack();
            return $this->error($e->getMessage());
        }
        if($is_register){
            $this->eventDispatcher->dispatch(new UserRegister($user,$data));
        }
        $token = (string) $this->jwt->getToken(['user_id' => $user->id]);
        $account = UserAccountRepository::getInstance()->one('*',[[
            'field' => 'user_id',
            'value' => $user->id
        ]]);
        $user=collect($user)->toArray();
        $account = collect($account)->toArray();
        $user['account'] = $account;
        return $this->success([
            'user' => $user,
            'access_token' => $token,
            'expires_in' => $this->jwt->getTTL(),
        ]);
    }

    public function userSync($data){
        $where = [
            [
                'field' => 'mobile',
                'value' => $data['mobile']
            ]
        ];
        $user = UserRepository::getInstance()->one('*',$where);
        $is_register = false;
        DB::beginTransaction();
        try {
            if(!$user){
                $is_register = true;
                $user_data =[
                    'username' => $data['username'],
                    'password' => password_hash(md5(config('common.init_pwd')),PASSWORD_BCRYPT),
                    'mobile' => $data['mobile'],
                    'status' => User::STATUS_ON,
                    'reg_time' => $data['reg_time'],
                    'union_id' => $data['union_id'],
                    'reg_ip' => $data['reg_ip'],
                    'is_virtual' => isset($data['is_virtual'])?$data['is_virtual']:0
                ];
                $return = UserRepository::getInstance()->store($user_data);
                if(!$return['success']){
                    throw new \Exception('用户创建失败');
                }
                $user = $return['data'];
                $account_return = UserAccountRepository::getInstance()->store([
                    'user_id'=> $user->id,
                    'balance' => 0,
                    'used_balance' => 0,
                    'frozen_balance' => 0
                ]);
                if(!$account_return['success']){
                    throw new \Exception('用户账户创建失败');
                }
                //保存微信信息
            }
            $wechat_user = UserWechatRepository::getInstance()->one('*', [
                [
                    'field' => 'user_id',
                    'value' => $user->id
                ]
            ]);
            $wechat_data=[
                'id' => $wechat_user?$wechat_user->id:0,
                'wx_openid' => $data['wx_openid'],
                'wx_nickname' => $data['wx_nickname'],
                'wx_avatar' => $data['wx_avatar'],
                'user_id' => $user->id
            ];
            $return_wechat = UserWechatRepository::getInstance()->store($wechat_data);
            if(!$return_wechat['success']){
                throw new \Exception('微信信息同步失败');
            }
            DB::commit();
        }catch(\Exception $e){
            DB::rollBack();
            return $this->error($e->getMessage());
        }
        if($is_register){
            $this->eventDispatcher->dispatch(new UserRegister($user,$data));
        }
        $user=collect($user)->toArray();
        return $this->success([
            'user' => $user,
            'is_register' => $is_register//是否新注册会员
        ]);
    }


    public function delete($user_id){
        DB::beginTransaction();
        try {
            //删除账户
            $delete_account= UserAccount::query()->where('user_id',$user_id)->delete();
            if(!$delete_account){
                throw new \Exception('账户信息删除失败');
            }
            //删除微信
            $delete_wechat = UserWechat::query()->where('user_id',$user_id)->delete();
            if(!$delete_wechat){
                throw new \Exception('微信信息删除失败');
            }
            //删除用户
            $delete_user=UserRepository::getInstance()->delete($user_id);
            if(!$delete_user){
                throw new \Exception('用户信息删除失败');
            }
            DB::commit();
        }catch(\Throwable $e){
            DB::rollBack();
            return $this->error($e->getMessage());
        }
        return $this->success();
    }

    public function visitor(RequestInterface $request){
        $user_agent = $request->getHeaderLine('user-agent');
        $ip = Utils::ip();
        $visitor_id = md5($ip.$user_agent);

        return $request->getHeaderLine('user-agent');
    }

    public function storeInfoBasic($user,$data){
        $info = $user->info;
        if(!$info){
            $info = new UserInfo();
            $info->user_id = $user->id;
        }
        $info->fill($data);
        DB::beginTransaction();
        try {
            if(!$info->save()){
                throw new \Exception('基本信息保存失败');
            }
            DB::commit();
        }catch(\Throwable $e){
            DB::rollBack();
            return $this->error($e->getMessage());
        }
        return $this->success([]);
    }
}